package org.protocol;

import org.jetlinks.core.ProtocolSupport;
import org.jetlinks.core.Value;
import org.jetlinks.core.defaults.CompositeProtocolSupport;
import org.jetlinks.core.device.AuthenticationResponse;
import org.jetlinks.core.device.MqttAuthenticationRequest;
import org.jetlinks.core.message.codec.DefaultTransport;
import org.jetlinks.core.metadata.DefaultConfigMetadata;
import org.jetlinks.core.metadata.DeviceConfigScope;
import org.jetlinks.core.metadata.types.PasswordType;
import org.jetlinks.core.metadata.types.StringType;
import org.jetlinks.core.route.Route;
import org.jetlinks.core.spi.ProtocolSupportProvider;
import org.jetlinks.core.spi.ServiceContext;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.Objects;

public class MyProtocolSupportProvider implements ProtocolSupportProvider {
    public Mono<? extends ProtocolSupport> create(ServiceContext serviceContext) {
        CompositeProtocolSupport support = new CompositeProtocolSupport();
        support.setId("custom-protocol");
        support.setName("custom-protocol");

        support.addMessageCodecSupport(new MqttDeviceMessageCodec());

        //MQTT 认证
        support.addAuthenticator(DefaultTransport.MQTT, (request, device) -> {
            MqttAuthenticationRequest mqttRequest = ((MqttAuthenticationRequest) request);
            return device
                .getConfigs("username", "password")
                .flatMap(values -> {
                    String username = values
                        .getValue("username")
                        .map(Value::asString)
                        .orElse(null);

                    String password = values
                        .getValue("password").map(Value::asString)
                        .orElse(null);

                    //对比用户名密码
                    if (Objects.equals(mqttRequest.getUsername(), username)
                        && Objects.equals(mqttRequest.getPassword(), password)) {
                        return Mono.just(AuthenticationResponse.success());
                    } else {
                        return Mono.just(AuthenticationResponse.error(400, ""));
                    }
                });
        });

        //设置配置定义信息
        support.addConfigMetadata(DefaultTransport.MQTT,
            new DefaultConfigMetadata("MQTT认证配置", "MQTT接入时使用的认证配置")
                //产品和设备都可以配置
                .scope(DeviceConfigScope.device, DeviceConfigScope.product)
                .add("username", "username", "MQTT用户名", StringType.GLOBAL)
                .add("password", "password", "MQTT密码", PasswordType.GLOBAL)
        );

        support.addRoutes(DefaultTransport.MQTT, Arrays.asList(
            Route.mqtt("/properties/report")
                .group("属性相关")
                .description("上报属性")
                .upstream(true)
                .build(),
            Route.mqtt("/function/{functionId}")
                .group("功能相关")
                .description("平台下发功能调用指令")
                .downstream(true)
                .build()
        ));

        return Mono.just(support);
    }
}
